﻿using Artech.Common;
using Artech.Core.Caching;
using Artech.Core.Resources.Configuration;
using Artech.Core.Wcf;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.Unity.Utility;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Artech.Core.Resources
{
    [ConfigurationElementType(typeof(WcfResourceProviderData))]
    public class WcfResourceProvider: ResourceProviderBase, IWcfProvider<IResourceService>
    {
        public WcfInvoker<IResourceService> Invoker { get; private set; }
        public WcfResourceProvider(string endpointName, bool cacheEnabled, CacheGranularity cacheGranularity, Func<ICacheStore<IEnumerable<StringResourceItem>>> cacheStoreAccessor)
            : base(cacheEnabled, cacheGranularity, cacheStoreAccessor)
        {
            Guard.ArgumentNotNullOrEmpty(endpointName, "endpointName");
            this.Invoker = new WcfInvoker<IResourceService>(endpointName);
        }

        protected internal override IEnumerable<StringResourceItem> GetStringsCore(CultureInfo culture)
        {
            Guard.ArgumentNotNull(culture, "culture");
            return this.Invoker.Invoke<StringResourceItem[]>(proxy=>proxy.GetAllStrings(culture.Name));
        }

        protected internal override IEnumerable<StringResourceItem> GetStringsCore(string category, CultureInfo culture)
        {
            Guard.ArgumentNotNullOrEmpty(category, "category");
            Guard.ArgumentNotNull(culture, "culture");
            return this.Invoker.Invoke<StringResourceItem[]>(proxy => proxy.GetStringsByCategory(category, culture.Name));
        }

        protected internal override IEnumerable<StringResourceItem> GetStringsCore(string category, string name, CultureInfo culture)
        {
            Guard.ArgumentNotNullOrEmpty(category, "category");
            Guard.ArgumentNotNullOrEmpty(name, "name");
            Guard.ArgumentNotNull(culture, "culture");
            return this.Invoker.Invoke<StringResourceItem[]>(proxy => proxy.GetStringsByName(category, name, culture.Name));
        }

        public override StatefulEntryCollection<StringResourceEntry> GetStringsForEdit(StringResourceSearchCriteria criteria, int pageSize, int pageIndex, ResourceEntryField orderBy, SortDirection sortDirection)
        {
            Guard.ArgumentNotNull(criteria, "criteria");
            Guard2.ArgumentIsValidePageSize(pageSize, "pageSize");
            Guard2.ArgumentIsValidePageIndex(pageIndex, "pageIndex");
            Guard.ArgumentNotNull(orderBy, "orderBy");
            
            StringResourceEntry[] entries = this.Invoker.Invoke<StringResourceEntry[]>(proxy=>proxy.GetStringsForEdit(criteria,pageSize,pageIndex,orderBy,sortDirection));
            return new StatefulEntryCollection<StringResourceEntry>(entries);
        }

        public override void UpdateStrings(StatefulEntryCollection<StringResourceEntry> resourceEntries)
        {
            Guard.ArgumentNotNull(resourceEntries, "resourceEntries");
            if (resourceEntries.GetChanges().Any())
            { 
                this.Invoker.Invoke(proxy=> proxy.UpdateStrings(resourceEntries.ToArray()));
            }
        }
    }
}
